home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / PROG_TOO / C027B.ZIP / JAS / OPT.C < prev    next >
Text File  |  1990-03-30  |  3KB  |  133 lines

  1.  
  2. /*
  3.  * Copyright (c) 1988 by Sozobon, Limited.  Author: Joseph M Treat
  4.  *
  5.  * Permission is granted to anyone to use this software for any purpose
  6.  * on any computer system, and to redistribute it freely, with the
  7.  * following restrictions:
  8.  * 1) No charge may be made other than reasonable charges for reproduction.
  9.  * 2) Modified versions must be clearly marked as such.
  10.  * 3) The authors are not responsible for any harmful consequences
  11.  *    of using this software, even if they result from defects in it.
  12.  */
  13.  
  14. #include "jas.h"
  15.  
  16. BRANCH *brlist = (BRANCH *) NULL;
  17.  
  18. add_brnch( cptr, where )
  19.     CBUF *cptr;
  20.     long where;
  21. {
  22.     register BRANCH *bp;
  23.  
  24.     bp = ALLO(BRANCH);
  25.  
  26.     bp->where = where;
  27.     bp->cptr = cptr;
  28.     bp->link = brlist;
  29.     brlist = bp;
  30. }
  31.  
  32. do_opt()
  33. {
  34.     BRANCH *bp, **lbp;
  35.     register CBUF *cp;
  36.     SYM *sp;
  37.     register int changed = 0;
  38.     extern long dottxt;
  39.  
  40.     /* 
  41.      * first take care of jsr's to external routines
  42.      */
  43.     lbp = &brlist;
  44.     for ( bp = brlist; bp != (BRANCH *) NULL; bp = bp->link ) {
  45.         cp = bp->cptr;
  46.         if ( cp->value.value != 0x61 /* BSR */ ) {
  47.             lbp = &bp->link;
  48.             continue;
  49.         }
  50.         sp = cp[1].value.psym;
  51.         if ( sp->flags & SEGMT ) {
  52.             lbp = &bp->link;
  53.             continue;
  54.         }
  55.         /* 
  56.          * change it to a jsr
  57.          */
  58.         cp[0].nbits = 16;
  59.         cp[0].value.value = 0x4eb9;    /* jsr abs.l */
  60.         cp[1].nbits = 32;
  61.         cp[1].action = GENRELOC;
  62.         dottxt += 4;
  63.         /*
  64.          * move all text symbols after this point up four bytes
  65.          */
  66.         fixsymval( bp->where, 4L, TXT );
  67.         /*
  68.          * move the location of all branches after this point up
  69.          */
  70.         {
  71.             register BRANCH *xbp;
  72.  
  73.             for ( xbp = brlist; xbp != bp; xbp = xbp->link )
  74.                 xbp->where += 4;
  75.         }
  76.         /*
  77.          * remove this entry from the branch list
  78.          */
  79.         *lbp = bp->link;
  80.         /*
  81.          * don't bother to free it, it will just make later ALLO's 
  82.          * slower
  83.          */
  84.     }
  85.     /* 
  86.      * now do normal branches and remaining bsr's
  87.      */
  88.     do {
  89.         changed = 0;
  90.  
  91.         lbp = &brlist;
  92.         for ( bp = brlist; bp != (BRANCH *) NULL; bp = bp->link ) {
  93.             register long val;
  94.  
  95.             cp = bp->cptr;
  96.             sp = cp[1].value.psym;
  97.  
  98.             val = cp[1].value.value + sp->value - bp->where;
  99.             if ( val >= -128 && val <= 127 && val != 0 ) {
  100.                 lbp = &bp->link;
  101.                 continue;
  102.             }
  103.             /* 
  104.              * change it to a 16-bit displacement
  105.              */
  106.             cp[0].nbits = 16;
  107.             cp[0].value.value <<= 8;
  108.             cp[1].nbits = 16;
  109.             cp[1].action = GENPCREL;
  110.             dottxt += 2;
  111.             /*
  112.              * move all text symbols after this point up two bytes
  113.              */
  114.             fixsymval( bp->where, 2L, TXT );
  115.             /*
  116.              * move the location of all branches after this point up
  117.              */
  118.             {
  119.                 register BRANCH *xbp;
  120.     
  121.                 for ( xbp = brlist; xbp != bp; xbp = xbp->link )
  122.                     xbp->where += 2;
  123.             }
  124.             /*
  125.              * remove this entry from the branch list
  126.              */
  127.             *lbp = bp->link;
  128.             changed = 1;
  129.         }
  130.  
  131.     } while ( changed );
  132. }
  133.